home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / comt010d.zip / COMTSRC.ZIP / COMT.C < prev    next >
C/C++ Source or Header  |  1992-06-18  |  11KB  |  418 lines

  1. /********************************************/
  2. /*** Copyright 1991, 1992 Alexander Pruss ***/
  3. /***        Some rights reserved          ***/
  4. /********************************************/
  5.  
  6. /** SEE LICENSE.DOC for LICENSING INFORMATION **/
  7.  
  8. /*
  9.  *
  10.  * Encode a file using the OBFuscated methods
  11.  *
  12.  */
  13.  
  14. /*
  15.  * Revision:
  16.  *  0.00  -- 1-2 encoding only
  17.  *  0.10  -- 3-4 encoding added
  18.  *  0.10b -- converted to stdio, extractor added
  19.  *  0.10c -- -n option added
  20.  *  0.10d -- W initiator changed to < in 3->4 method
  21.  *        -- a possible major bug fixed, which might have caused
  22.  *           problems on systems with large prefetch queues
  23.  *        -- bug in Makefile fixed
  24.  *
  25.  */
  26.  
  27. /**
  28.  ** export version 0.10d
  29.  **/
  30.  
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <dir.h>
  34. #include <dos.h>
  35. #include <sys/stat.h>
  36.  
  37. #include "getopt.h"
  38. #include "header.h"
  39.  
  40. #define B_SIG  "S&$ig(Ap"
  41. #define B_SLEN 8
  42.  
  43. #define SUUSTYLE "uu00"
  44. #define SABSTYLE "ab00"
  45. #define E_LEN 4
  46.  
  47. #define Fwrite(fd,buf,len) fwrite((buf),1,(len),(fd))
  48. #define Fread(fd,buf,len) fread((buf),1,(len),(fd))
  49.  
  50. extern char decoded_to_end;
  51. extern char file_size_mod3;
  52.  
  53. typedef struct
  54. {
  55.   char sighead[B_SLEN];
  56.   char etype[E_LEN];
  57.   char len[8];  /* HEX--long */
  58.   char trailer[40];
  59. } sig;
  60.  
  61. unsigned long filelen;
  62.  
  63. char uutrailer[]="<\n";
  64. char ntrailer[]="\n";
  65.  
  66. char wrapname[70];
  67. int newwrapname=0;
  68.  
  69. char topwrap[]=
  70. "This file has been encoded with the COMT encoder.\n"
  71. "This encoding renders it a text file but makes it still possible to run the\n"
  72. "program in its text file format.\n\n"
  73. "Simply cut out the portion of the file between the --BEGIN and --END lines,\n"
  74. "save as `%s', making sure you have left no blank lines at the top,\n"
  75. "and that the first line of the file begins with `ENC.COM.'\n"
  76. "Make sure you save as a DOS text file (you can check by TYPE'ing the file,\n"
  77. "and seeing if all the text is nicely aligned at the left hand margin, and\n"
  78. "there are no graphics or control characters).  Then run %s.\n\n"
  79. "--BEGIN clear text of %s via COMT--CUT HERE--REMOVE THIS LINE TOO!\n";
  80.  
  81. char botwrap[]=
  82. "--END clear text of %s via COMT--CUT HERE.\n";
  83.  
  84. enum styles
  85. {
  86.   UUSTYLE, ABSTYLE, AUTO
  87. } method=AUTO;
  88.  
  89. enum logic
  90. {
  91.   FALSE=0, TRUE
  92. } wrap=FALSE;
  93. enum logic extractmode=FALSE;
  94.  
  95. sig mainsig;
  96.  
  97. unsigned uuencode_block(char *outblock, char *inblock, unsigned len);
  98. unsigned nencode_block(char *outblock, char *inblock, unsigned len);
  99.  
  100. #define IBSIZE (3*2048) /* must be divisible by 3 */
  101. #define OBSIZE (3*2*2250)
  102. int n_inbuf;
  103. char inbuf[IBSIZE];
  104. char outbuf[OBSIZE];
  105.  
  106.  
  107. enum styles decide(unsigned long l)
  108. {
  109.   long uu,ab;
  110.   if(method!=AUTO) return method;
  111.   uu=l*4/3+sizeof(uheader)-1+sizeof(uutrailer)-1;
  112.   ab=l*2+sizeof(nheader)-1+sizeof(ntrailer)-1;
  113.   if(uu<ab) return UUSTYLE; else return ABSTYLE;
  114. }
  115.  
  116. int encode(char *outblock, char *inblock, unsigned len)
  117. {
  118.   switch(method)
  119.   {
  120.     case ABSTYLE: return nencode_block(outblock, inblock, len);
  121.     case UUSTYLE: len=(len+2)/3;
  122.        /* this maps 0->0 and handles last block right */
  123.                   return uuencode_block(outblock, inblock, len);
  124.   }
  125. }
  126.  
  127.  
  128. void makesig(unsigned long length)
  129. {
  130.   char num[9];
  131.   strncpy(mainsig.sighead,B_SIG,B_SLEN);
  132.   switch(method)
  133.   {
  134.     case ABSTYLE: strncpy(mainsig.etype,SABSTYLE,E_LEN);
  135.       strncpy(mainsig.trailer,ntrailer,sizeof(ntrailer)-1); break;
  136.     case UUSTYLE: strncpy(mainsig.etype,SUUSTYLE,E_LEN);
  137.       strncpy(mainsig.trailer,uutrailer,sizeof(uutrailer)-1); break;
  138.   }
  139.   sprintf(num,"%.8lX",length);
  140.   strncpy(mainsig.len,num,8);
  141. }
  142.  
  143. int skipsig(FILE *in)
  144. {
  145.   int found=0;
  146.   while(NULL!=fgets(inbuf,IBSIZE,in))
  147.     if(!strncmp(inbuf,B_SIG,B_SLEN))
  148.     {
  149.       found=1;
  150.       break;
  151.     }
  152.   if(!found)
  153.   {
  154.     fputs("Cannot find the COMT signature.\n",stderr);
  155.     return -1;
  156.   }
  157.   memcpy(&mainsig,inbuf,sizeof mainsig);
  158.   if(!strncmp(mainsig.etype,SUUSTYLE,E_LEN))
  159.     method=UUSTYLE;
  160.   else if(!strncmp(mainsig.etype,SABSTYLE,E_LEN))
  161.     method=ABSTYLE;
  162.   else
  163.   {
  164.     strncpy(outbuf,mainsig.etype,E_LEN);
  165.     outbuf[E_LEN]=0;
  166.     fprintf(stderr,"I do not know `%s' encoding.  Probably this version is too old.\n"
  167.        ,outbuf);
  168.     return -1;
  169.   }
  170.   sscanf(mainsig.len,"%8lX",&filelen);
  171.   return 0;
  172. }
  173.  
  174.  
  175.  
  176. void sendhead(FILE *out, unsigned long len, char *name)
  177. {
  178.   if(wrap)
  179.   {
  180.     if(newwrapname) sprintf(outbuf,topwrap,wrapname,wrapname,wrapname);
  181.      else sprintf(outbuf,topwrap,name,name,name);
  182.     Fwrite(out,outbuf,strlen(outbuf));
  183.   }
  184.   switch(method)
  185.   {
  186.     case UUSTYLE: Fwrite(out,uheader,sizeof uheader-1); break;
  187.     case ABSTYLE: Fwrite(out,nheader,sizeof nheader-1); break;
  188.   }
  189.   makesig(len);
  190.   Fwrite(out,&mainsig,strlen((char *)&mainsig));
  191. }
  192.  
  193. #define SSTR(f,x)  Fwrite((f),(x),sizeof(x)-1)
  194.  
  195. void sendtail(FILE *out, char *name)
  196. {
  197.   static char uutail[]="\nz!#\n";  /* # in 4th position */
  198.   switch(method)
  199.   {                  /*  01234 */
  200.     case UUSTYLE: uutail[3]='0'+(n_inbuf%3); /* How many of last 3 are real */
  201.                   SSTR(out,uutail); break;
  202.     case ABSTYLE: SSTR(out,"\nZ\n"); break;
  203.   }
  204.   if(wrap)
  205.   {
  206.     sprintf(outbuf,botwrap,newwrapname?wrapname:name);
  207.     Fwrite(out,outbuf,strlen(outbuf));
  208.   }
  209. }
  210.  
  211. unsigned int fill_inbuf(FILE *f)
  212. {
  213.   n_inbuf=Fread(f,inbuf,IBSIZE);
  214.   if(n_inbuf<0) return 0; else return n_inbuf;
  215. }
  216.  
  217. unsigned int fill_outbuf(FILE *f)
  218. {
  219.   n_inbuf=Fread(f,outbuf,OBSIZE-256);
  220.   if(n_inbuf<0) return 0;
  221.   outbuf[n_inbuf]=0;
  222.   fgets(outbuf+n_inbuf,256,f);  /* make sure we end on an EOL */
  223.   n_inbuf+=strlen(outbuf+n_inbuf);
  224.   return n_inbuf;
  225. }
  226.  
  227.  
  228. void usage(int rval)
  229. {
  230.   static char umsg[]=
  231. "comt [-1 -3 -w -nname|-x|-h] name[.COM] [outputname]\n"
  232. "Options:\n"
  233. " -x  Extract from file\n"
  234. " -1  Use 1->2 encoding\n"
  235. " -3  Use 3->4 encoding\n"
  236. " -w  Wrap in a text wrapper\n"
  237. " -nname  Set name to wrap as\n"
  238. " -h  This help information\n\n"
  239. "By default the input file is overwritten.  If -w is specified, the\n"
  240. "output file name.ASC is by default created, unless the outputname\n"
  241. "is specified.  Default extension on outputname is .COM except in -w\n"
  242. "mode where .ASC is used.\n\n"
  243. "COMT ver. 0.10d is Copyright 1991,1992 Alexander Pruss.  Some rights reserved.\n"
  244. "  All use is permitted limited only by the law of the land and natural law.\n"
  245. "  I hereby specify that only the exact version I produced belongs to me.\n"
  246. "  Any modification, however trivial, renders my rights to this null and void.\n"
  247. "  Thus, if you change this copyright message this program shall no longer\n"
  248. "  belong to me.  I permit any such modification, and I permit any removal\n"
  249. "  of credit to myself for this programme.  NO WARRANTY OF ANY KIND IS IMPLIED.\n"
  250. "  Interpretation of natural law is left to the user.\n";
  251.   Fwrite(stdout,umsg,sizeof umsg-1);
  252.   exit(rval);
  253. }
  254.  
  255. void notfound(char *name)
  256. {
  257.   Fwrite(stderr,outbuf,sprintf(outbuf,"I cannot find `%s'.\n",name));
  258.   exit(3);
  259. }
  260.  
  261. void err(char *d)
  262. {
  263.   Fwrite(stderr,outbuf,sprintf(outbuf,"Error %s.\n",d));
  264.   exit(4);
  265. }
  266.  
  267. int have_ext(char *path)
  268. {
  269.   char drive[3];
  270.   char dir[80];
  271.   char name[9];
  272.   char ext[5];
  273.   return (EXTENSION&fnsplit(path,drive,dir,name,ext))?1:0;
  274. }
  275.  
  276.  
  277. main(int argc, char **argv)
  278. {
  279.   FILE *in;
  280.   FILE *out;
  281.   char tmp[15]="ARPXXXXX";
  282.   char temp[86];
  283.   char inname[84];
  284.   char outname[84];
  285.   int in_keep=0;
  286.   struct stat sb;
  287.   int option;
  288.   unsigned long totdec;
  289.   unsigned int curdec;
  290.  
  291.   char drive[3];
  292.   char dir[80];
  293.   char name[9];
  294.   char ext[5];
  295.   int flags;
  296.  
  297.   opterr=1;
  298.  
  299.   if(argc==1) usage(2);
  300.   while (-1!=(option=getopt(argc,argv,"13whxn:?")))
  301.     switch (option)
  302.     {
  303.       case '1': method=ABSTYLE; break;
  304.       case '3': method=UUSTYLE; break;
  305.       case 'w': wrap=1; break;
  306.       case 'h': usage(0); break;
  307.       case 'x': extractmode=1; break;
  308.       case '?': usage(0); break;
  309.       case 'n': strcpy(wrapname,optarg); newwrapname=1; break;
  310.     }
  311.  
  312.   flags=fnsplit(argv[optind],drive,dir,name,ext);
  313.   if(!(EXTENSION & flags))
  314.   {
  315.     sprintf(inname,"%s.COM",argv[o